package Email.auto.checker;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

/**
 * Class responsible for encrypt the password and username. The encryption is
 * made using the DES Algorithm and with a specific encryption key
 * 
 * @author Marcio Almeida
 * @author Mario Marques
 * @author Emanuel Bicho
 * 
 */
public class DESEncryption {

	/**
	 * Used to create the costume encryption key.
	 */
	private DESKeySpec keySpec = null;
	/**
	 * Used to get an instance of the algorithm to be used, in this case the
	 * DES.
	 */
	private SecretKeyFactory keyFactory = null;
	/**
	 * The secret generated key (based on the keySpec) used to encrypt and
	 * decrypt the strings.
	 */
	private SecretKey myDesKey = null;
	/**
	 * The cipher used to encrypt and decrypt the strings.
	 */
	private Cipher desCipher = null;

	/**
	 * Constructor for the encryption class.
	 * 
	 * @param key
	 *            - The encryption key used.
	 * @throws InvalidKeySpecException
	 *             - If the key if shorter that 8 bytes.
	 * @throws InvalidKeyException
	 *             - If the key size is .
	 */
	public DESEncryption(final String key) throws InvalidKeySpecException,
			InvalidKeyException {
		try {
			keySpec = new DESKeySpec(key.getBytes());

			keyFactory = SecretKeyFactory.getInstance("DES");
			myDesKey = keyFactory.generateSecret(keySpec);
			desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");

		} catch (NoSuchAlgorithmException e) {
			System.out.println(e.toString());
		} catch (NoSuchPaddingException e) {
			System.out.println(e.toString());
		}
	}

	/**
	 * Encrypts a string using the DES Algorithm.
	 * 
	 * @param str
	 *            - the string to encrypt.
	 * @return byte[] - the encrypted string.
	 */
	public final byte[] encrypt(final String str) {
		if (str == null || str.isEmpty()) {
			return null;
		}
		
		try {

			desCipher.init(Cipher.ENCRYPT_MODE, myDesKey);
			byte[] text = str.getBytes();

			// Encrypt the text
			byte[] textEncrypted = desCipher.doFinal(text);
			return textEncrypted;

		} catch (IllegalBlockSizeException e) {
			System.out.println(e.toString());
		} catch (BadPaddingException e) {
			System.out.println(e.toString());
		} catch (InvalidKeyException e) {
			System.out.println(e.toString());
		}
		return null;
	}

	/**
	 * Decrypt the given byte[].
	 * 
	 * @param str
	 *            - the byte[] to decrypt
	 * @return String - the decrypted string
	 */
	public final String desencrypt(final byte[] str) {
		
		if(str == null || str.length == 0){
			return null;
		}
		
		try {
			desCipher.init(Cipher.DECRYPT_MODE, myDesKey);
			byte[] textDecrypted = desCipher.doFinal(str);
			return new String(textDecrypted);

		} catch (IllegalBlockSizeException e) {
			System.out.println(e.toString());
		} catch (BadPaddingException e) {
			System.out.println(e.toString());
		} catch (InvalidKeyException e) {
			System.out.println(e.toString());
		}

		return null;
	}

}
